<script setup>
import { onMounted, ref, watch } from "vue";
import { ElDialog, ElForm, ElFormItem, ElInput, ElButton, ElContainer, ElAside, ElMain, ElTable, ElTableColumn, ElTabs, ElTabPane, ElMessageBox } from "element-plus";
import { AxiosError } from "axios";
import { ElMessage } from "element-plus";
import roleService from "@/services/role.service";
import { useRouter, useRoute } from "vue-router";
import ApiResourceHelp from "@/components/ApiResourceHelp.vue";
import MenuHelp from "@/components/MenuHelp.vue";
import menuService from "@/services/menu.service";
import apiResourceService from "@/services/api-resource.service";
import { Search, Refresh, Plus, Edit, Delete, View, Upload, Download, Share, Close } from "@element-plus/icons-vue";


const currentState = ref('VIEW');
const currentId = ref(-1);

const router = useRouter();
const route = useRoute();

const entity = ref({});
const saveLoading = ref(false);

const apiResources = ref([]);
const apiResourceSelections = ref([]);

const apiResourceHelpDialogVisible = ref(false);

const menus = ref([]);
const menuSelections = ref([]);

const menuHelpDialogVisible = ref(false);

onMounted(async () => {
    currentState.value = route.query.operation;
    currentId.value = Number(route.query.id);

    if (currentState.value == 'CREATE') {
        create();
    } else if (currentState.value == 'EDIT') {
        edit();
    }
});

const load = async () => {
    try {
        const e = await roleService.retrieve(currentId.value);
        entity.value = e;

        await loadApiResources();
        await loadMenus();
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {
    }
};

const create = async () => {
    entity.value = {};
    currentState.value = 'CREATE';
}


const edit = async () => {
    await load();
}

const save = async () => {
    try {
        saveLoading.value = true;
        let id;
        if (currentState.value == 'CREATE') {
            id = await roleService.insert(entity.value);
        } else if (currentState.value == 'EDIT') {
            await roleService.update(entity.value);
            id = entity.value.id;
        } else {
            id = undefined;
        }
        if (id) {
            currentId.value = id;
            edit();
            ElMessage({ message: "保存成功", type: "success" });
        }
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {
        saveLoading.value = false;
    }
}

const loadApiResources = async () => {
    try {
        apiResources.value = await apiResourceService.findApiResourcesByRoleId(entity.value.id);
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
}

const apiResourceSelectionChanged = (val) => {
    apiResourceSelections.value = val;
}

const addApiResources = () => {
    apiResourceHelpDialogVisible.value = true;
};

const removeApiResources = async (row) => {
    let ids = [];
    if (row != null) {
        if (!(row.requireLogin && row.requirePermissions)) {
            ElMessage({ message: "仅可删除需要指定角色访问的API资源", type: "error" });
            return;
        }
        ids = [row.id];
    } else {
        if (apiResourceSelections.value.some(it => !(it.requireLogin && it.requirePermissions))) {
            ElMessage({ message: "仅可删除需要指定角色访问的API资源", type: "error" });
            return;
        }
        ids = apiResourceSelections.value.map(it => it.id);
    }
    if (ids.length == 0) {
        ElMessage({ message: "请选择要删除的数据", type: "error" });
        return;
    }
    try {
        const flag = await ElMessageBox.confirm('确定要删除选中的数据吗');
        if (flag) {
            const param = {};
            param.roleId = entity.value.id;
            param.apiResourceIds = ids;
            await apiResourceService.cancelAssign(param);
            ElMessage({ message: "删除成功", type: "success" });
            load();
        }
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
};

const removeApiResourceRow = (row) => {
    removeApiResources(row);
};

const apiResourceHelpDialogConfirmed = async (selections) => {
    console.log(selections);
    try {
        const param = {};
        param.roleId = entity.value.id;
        param.apiResourceIds = selections.map(it => it.id);
        await apiResourceService.assign(param);
        ElMessage({ message: "新增成功", type: "success" });
        load();
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
}

const loadMenus = async () => {
    try {
        menus.value = await menuService.findMenusByRoleId(entity.value.id);
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
}

const menuSelectionChanged = (val) => {
    menuSelections.value = val;
}

const addMenus = () => {
    menuHelpDialogVisible.value = true;
};

const removeMenus = async (row) => {
    let ids = [];
    if (row != null) {
        ids = [row.id];
    } else {
        ids = menuSelections.value.map(it => it.id);
    }
    if (ids.length == 0) {
        ElMessage({ message: "请选择要删除的数据", type: "error" });
        return;
    }
    try {
        const flag = await ElMessageBox.confirm('确定要删除选中的数据吗');
        if (flag) {
            const param = {};
            param.roleId = entity.value.id;
            param.menuIds = ids;
            await menuService.cancelAssign(param);
            ElMessage({ message: "删除成功", type: "success" });
            load();
        }
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
};

const removeMenuRow = (row) => {
    removeMenus(row);
};

const menuHelpDialogConfirmed = async (selections) => {
    try {
        const param = {};
        param.roleId = entity.value.id;
        param.menuIds = selections.map(it => it.id);
        await menuService.assign(param);
        ElMessage({ message: "新增成功", type: "success" });
        load();
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
}
</script>

<template>
    <ElContainer>
        <ElAside style="width: 25%;">
            <ElForm v-model="entity" label-width="120px" class="form">
                <ElFormItem label="编号">
                    <ElInput v-model="entity.code"></ElInput>
                </ElFormItem>
                <ElFormItem label="名称">
                    <ElInput v-model="entity.name"></ElInput>
                </ElFormItem>
                <ElFormItem label="描述">
                    <ElInput v-model="entity.description"></ElInput>
                </ElFormItem>
                <ElFormItem>
                    <ElButton type="primary" :loading="saveLoading" @click="save()">保存</ElButton>
                </ElFormItem>
            </ElForm>
        </ElAside>
        <ElMain>
            <ElTabs>
                <ElTabPane label="菜单">
                    <div class="flex mt-2">
                        <ElButton size="small" :plain="true" type="primary" :icon="Plus" @click="addMenus()"
                            :disabled="entity.id == null">
                            新增
                        </ElButton>
                        <ElButton size="small" :plain="true" type="danger" :icon="Delete" @click="removeMenus()"
                            :disabled="entity.id == null">
                            删除
                        </ElButton>
                    </div>
                    <ElTable row-key="id" table-layout="auto" :data="menus"
                        @selection-change="menuSelectionChanged($event)">
                        <ElTableColumn type="selection" width="55" />
                        <ElTableColumn prop="name" label="名称"></ElTableColumn>
                        <!-- <ElTableColumn prop="code" label="编号"></ElTableColumn> -->
                        <ElTableColumn prop="type" label="类型">
                            <template #default="scope">
                                <span v-if="scope.row.type == 'DIRECTORY'">目录</span>
                                <span v-if="scope.row.type == 'MENU'">菜单</span>
                                <span v-if="scope.row.type == 'BUTTON'">按钮</span>
                            </template>
                        </ElTableColumn>
                        <ElTableColumn prop="icon" label="图标">
                            <template #default="scope">
                                <ElIcon v-if="scope.row.icon">
                                    <component :is="scope.row.icon"></component>
                                </ElIcon>
                            </template>
                        </ElTableColumn>
                        <ElTableColumn prop="display" label="是否显示">
                            <template #default="scope">
                                <span v-if="scope.row.display">是</span>
                                <span v-else>否</span>
                            </template>
                        </ElTableColumn>
                        <ElTableColumn prop="path" label="路由"> </ElTableColumn>
                        <ElTableColumn prop="selector" label="选择器"> </ElTableColumn>
                        <ElTableColumn prop="operation" label="操作">
                            <template #default="scope">
                                <ElButton size="small" link type="primary" :icon="Delete" @click="removeMenuRow(scope.row)"
                                    :disabled="entity.id == null">
                                    删除
                                </ElButton>
                            </template>
                        </ElTableColumn>
                    </ElTable>
                </ElTabPane>
                <ElTabPane label="API资源">
                    <div class="flex mt-2">
                        <ElButton size="small" :plain="true" type="primary" :icon="Plus" @click="addApiResources()"
                            :disabled="entity.id == null">
                            新增
                        </ElButton>
                        <ElButton size="small" :plain="true" type="danger" :icon="Delete" @click="removeApiResources()"
                            :disabled="entity.id == null">
                            删除
                        </ElButton>
                    </div>
                    <ElTable row-key="id" table-layout="auto" :data="apiResources"
                        @selection-change="apiResourceSelectionChanged($event)">
                        <ElTableColumn type="selection" width="55" />
                        <ElTableColumn prop="code" label="编号"></ElTableColumn>
                        <ElTableColumn prop="name" label="名称"></ElTableColumn>
                        <ElTableColumn prop="url" label="URL"></ElTableColumn>
                        <ElTableColumn prop="display" label="需要登录">
                            <template #default="scope">
                                <span v-if="scope.row.requireLogin">是</span>
                                <span v-else>否</span>
                            </template>
                        </ElTableColumn>
                        <ElTableColumn prop="display" label="需要授权">
                            <template #default="scope">
                                <span v-if="scope.row.requirePermissions">是</span>
                                <span v-else>否</span>
                            </template>
                        </ElTableColumn>
                        <ElTableColumn prop="description" label="描述"></ElTableColumn>
                        <ElTableColumn prop="operation" label="操作">
                            <template #default="scope">
                                <ElButton v-if="scope.row.requireLogin && scope.row.requirePermissions" size="small" link
                                    type="primary" :icon="Delete" @click="removeApiResourceRow(scope.row)"
                                    :disabled="entity.id == null">
                                    删除
                                </ElButton>
                            </template>
                        </ElTableColumn>
                    </ElTable>
                </ElTabPane>
            </ElTabs>

            <ApiResourceHelp ref="apiResourceHelpDialog" v-model:visible="apiResourceHelpDialogVisible"
                @confirm="apiResourceHelpDialogConfirmed">
            </ApiResourceHelp>

            <MenuHelp ref="roleHelpDialog" v-model:visible="menuHelpDialogVisible" @confirm="menuHelpDialogConfirmed">
            </MenuHelp>
        </ElMain>
    </ElContainer>
</template>

<style scoped>
.form {
    max-width: 460px;
}
</style>